
#include "usart.h"
#include <stdio.h>
#include <stdarg.h>
//#if 1

//#pragma import(_use_no_semihosting)
//struct __FILE
//{
//	int handle;
//};
//FILE __stdout;

//_sys_exit(int x)
//{
//	x = x;
//}

//int fputc(int ch, FILE *f) 
//{
////   USART_SendData(USART1, (uint8_t)ch);  // 发送字符到USART1
////   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送完成
//	  while((USART1->SR&0x40)==0);
//			USART1->DR=(uint8_t)ch;
//    return ch;
//}
//#endif
int fputc(int ch, FILE *f) 
{
   USART_SendData(USART1, (uint8_t)ch);  // 发送字符到USART1
   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送完成
//	  while((USART1->SR&0x40)==0);
//			USART1->DR=(uint8_t)ch;
    return ch;
}
/*************************************
 
-----------------------
 *          | PA9  - USART1(Tx)      |
 *          | PA10 - USART1(Rx)      |
 *           ------------------------
**********************************************************************************/

void USART1_Init(void)
{
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 开启外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); 

    // Tx PA9发送                                        
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // Rx PA10接收
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode =  USART_Mode_Tx|USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1, ENABLE);

    // 配置中断
//    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_Init(&NVIC_InitStructure);

//    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

}


/**
  * 函    数：使用printf需要重定向的底层函数
  * 参    数：保持原始格式即可，无需变动
  * 返 回 值：保持原始格式即可，无需变动
  */
//int fputc(int ch, FILE *f)
//{
//	USART1_SendChar(ch);			//将printf的底层重定向到自己的发送字节函数
//	return ch;
//}



void USART1_SendChar(uint8_t ch)
{
    // 发送字符
    USART_SendData(USART1, ch);
    // 等待发送缓冲区为空
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    
}

// 接收中断
//void USART1_IRQHandler(void)
//{
//    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//    {
//        // 读取接收到的数据
//        char ch = USART_ReceiveData(USART1);
//        // 处理接收到的数据
//        // TODO: 在这里添加你的代码
//        USART1_SendChar(ch);
//    }
//}




// 函数：USART1_SendChar
// 功能：发送一个字符
// 参数：ch，要发送的字符
// void USART1_SendChar(char ch)
// {
//     // 发送字符
//     USART_SendData(USART1, ch);
//     // 等待发送缓冲区为空
//     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    
// }





 /* ÃèÊö  £ºÖØ¶¨Ïòc¿âº¯Êýprintfµ½USART1*/ 
//int fputc(int ch, FILE *f)
//{
///* ½«PrintfÄÚÈÝ·¢Íù´®¿Ú */
//  USART_SendData(USART1, (unsigned char) ch);
//  while (!(USART1->SR & USART_FLAG_TXE));
// 
//  return (ch);
//}



// 发送字符串
void USART1_SendString(char *str)
{
    while (*str)
    {
        USART1_SendChar(*str++);
    }
}

/**
  * 函    数：自己封装的prinf函数
  * 参    数：format 格式化字符串
  * 参    数：... 可变的参数列表
  * 返 回 值：无
  */
 void Serial_Printf(char *format, ...)
 {
     char String[100];				//定义字符数组
     va_list arg;					//定义可变参数列表数据类型的变量arg
     va_start(arg, format);			//从format开始，接收参数列表到arg变量
     vsprintf(String, format, arg);	//使用vsprintf打印格式化字符串和参数列表到字符数组中
     va_end(arg);					//结束变量arg
     USART1_SendString(String);		//串口发送字符数组（字符串）
}

 